#include <string.h>
#include <stdint.h>

#include "check.h"
#include "tabs.h"

START_TEST(test_ok) {
    tab_handler *handler = NULL;
    ck_assert_int_eq(common_tabs_init(&handler), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_add_header(handler, 3, "header1", "header2", "header3"), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_add_data(handler, 3, "data1", "data2", "data3"), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_print_ascii_tabs(handler), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_free(&handler), COMMON_TABS_OK);
    ck_assert_ptr_eq(handler, NULL);
}
END_TEST

START_TEST(test_input) {
    // 正常使用的句柄
    tab_handler *handler = NULL;
    // 初始化但未添加表头的句柄
    tab_handler *handler2 = NULL;

    // 初始化检查
    ck_assert_int_eq(common_tabs_init(&handler), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_init(&handler2), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_init(NULL), COMMON_TABS_BAD_INPUT);
    ck_assert_int_eq(common_tabs_init(&handler), COMMON_TABS_ALREADY_INITED);

    // 添加表头检查
    ck_assert_int_eq(common_tabs_add_header(handler, 3, "header1", "header2", NULL), COMMON_TABS_BAD_INPUT);
    ck_assert_int_eq(common_tabs_add_header(handler, -1, "header1", "header2", "header3"), COMMON_TABS_BAD_INPUT);
    ck_assert_int_eq(common_tabs_add_header(handler, 3, "header1", "header2", "header3"), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_add_header(handler, 3, "header1", "header2", "header3"), COMMON_TABS_ALREADY_INITED);
    ck_assert_int_eq(common_tabs_add_header(NULL, 3, "header1", "header2", "header3"), COMMON_TABS_BAD_INPUT);

    // 添加数据检查
    ck_assert_int_eq(common_tabs_add_data(handler, 3, "data1", "data2", "data3"), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_add_data(handler, 4, "data1", "data2", "data3"), COMMON_TABS_HEADER_AND_DATA_MISMATCH);
    ck_assert_int_eq(common_tabs_add_data(handler, 3, "data1", "data2", NULL), COMMON_TABS_BAD_INPUT);
    ck_assert_int_eq(common_tabs_add_data(handler, 0, "data1", "data2", "data3"), COMMON_TABS_BAD_INPUT);
    ck_assert_int_eq(common_tabs_add_data(NULL, 3, "data1", "data2", "data3"), COMMON_TABS_BAD_INPUT);
    ck_assert_int_eq(common_tabs_add_data(handler2, 3, "data1", "data2", "data3"), COMMON_TABS_HEADERS_ARE_REQUIRED);

    ck_assert_int_eq(common_tabs_print_ascii_tabs(handler), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_print_ascii_tabs(NULL), COMMON_TABS_NEED_INIT);
    ck_assert_int_eq(common_tabs_print_ascii_tabs(handler2), COMMON_TABS_HEADERS_ARE_REQUIRED);

    ck_assert_int_eq(common_tabs_free(&handler), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_free(NULL), COMMON_TABS_BAD_INPUT);
    ck_assert_int_eq(common_tabs_free(&handler2), COMMON_TABS_OK);
    ck_assert_int_eq(common_tabs_free(&handler), COMMON_TABS_OK);

    ck_assert_ptr_eq(handler, NULL);
    ck_assert_ptr_eq(handler2, NULL);
}

Suite *check_tabs(void)
{
    Suite *s;
    TCase *tc_core;

    s = suite_create("tabs check");

    tc_core = tcase_create("core");
    tcase_add_test(tc_core, test_ok);
    tcase_add_test(tc_core, test_input);

    suite_add_tcase(s, tc_core);

    return s;
}